﻿#include "widget.h"
#include "ui_widget.h"

/***************************************************************
    initClientSignals()
    初始化客户端信号槽
    将客户端的函数与获取的信号相关联
*****************************************************************/
void Widget::initClientSignals()
{
    connect(&m_client, SIGNAL(connected()), this, SLOT(onClientConnected()));
    connect(&m_client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
    connect(&m_client, SIGNAL(readyRead()), this, SLOT(onClientDataReady()));
    connect(&m_client, SIGNAL(bytesWritten(qint64)), this, SLOT(onClientBytesWritten(qint64)));
    connect(&m_client, SIGNAL(error(QAbstractSocket::SocketError )), this, SLOT(onClientErr(QAbstractSocket::SocketError)));
}

/*********************************************************************
    startClient()
    启动客户端
    获取客户端状态下的IP地址，并在应用程序输出框输出，
    同时进行800毫秒连接判断，若连接超时进行提醒
    关联函数：onClientConnected()，onClientDisconnected()，onClientErr(QAbstractSocket::SocketError socketError)
************************************************************************/
bool Widget::startClient()
{
    QString ip = QString("%1.%2.%3.%4")
            .arg(ui->ipAddr1->text())
            .arg(ui->ipAddr2->text())
            .arg(ui->ipAddr3->text())
            .arg(ui->ipAddr4->text());
    qDebug()<<ip;
    m_client.connectToHost(ip, ui->ipPort->text().toInt());
    if(m_client.waitForConnected(800))
    {
        return true;
    }
    else
    {
        QMessageBox::information(this,"提示",QString("连接超时"),QMessageBox::Ok);
        return false;
    }
}

/***********************************************************************
    onClientConnected()
    连接成功提醒
    连接成功后，在底部localPort显示本地端口号
    关联函数：startConnect(true);
************************************************************************/
void Widget::onClientConnected()
{
    startConnect(true);
    QMessageBox::information(this,"提示","连接成功",QMessageBox::Ok);
    ui->localPort->setText(QString("%1").arg(m_client.localPort())); //显示本地端口号
}

/***********************************************************************
    onClientDisconnected()
    连接断开提醒
    关联函数：startConnect(false);
************************************************************************/
void Widget::onClientDisconnected()
{
    startConnect(false);
    QMessageBox::information(this,"提示","断开完成",QMessageBox::Ok);
}

/***********************************************************************
    onClientDataReady()
    信息接受函数
    获取服务器端发来的信息，并在recvEdit上显示
************************************************************************/
void Widget::onClientDataReady()
{
    if(m_client.peerAddress().toString()!=targetAddr || m_client.peerPort()!=targetPort  )
    {
        targetAddr = m_client.peerAddress().toString();
        targetPort = m_client.peerPort();
        ui->recvEdit->insertPlainText("[接受来自"+ targetAddr+":"+QString("%1").arg(targetPort)+"]:\r\n");
    }
    ui->recvEdit->moveCursor(QTextCursor::End);
    ui->recvEdit->insertPlainText(QString::fromLocal8Bit(m_client.readAll())+"\r\n");
}

/***********************************************************************
    onClientBytesWritten(qint64 bytes)
    更新下方sendLenLabel（发送条数）信息
************************************************************************/
void Widget::onClientBytesWritten(qint64 bytes)
{
    qDebug() << "onBytesWritten:" << bytes;
    ui->sendLenLabel->setText(QString("%1").arg(ui->sendLenLabel->text().toInt()+bytes));
}

/***********************************************************************
    onClientErr(QAbstractSocket::SocketError socketError)
    连接失败提醒
    在应用程序输出框输出连接失败原因
    关联函数：startConnect(false)
************************************************************************/
void  Widget::onClientErr(QAbstractSocket::SocketError socketError)
{
    qDebug()<<"onClientErr:"<<socketError;
    m_client.close();
    startConnect(false);
    QMessageBox::information(this,"提示",QString("连接失败:%1").arg((int)socketError),QMessageBox::Ok);
}
